// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
#include "pch.h"
#include "DataModel\ForecastManager.h"
#include "UserSettings.h"

using namespace Weathr;

using namespace Platform;
using namespace Windows::Storage;

const TemperatureUnit TemperatureUnitDefault = TemperatureUnit::Celsius;

#ifdef _M_ARM
const bool ShowWeatherEffectsDefault = false;
#else
const bool ShowWeatherEffectsDefault = true;
#endif

#ifdef _M_ARM
const bool ShowStarfieldDefault = false;
#else
const bool ShowStarfieldDefault = true;
#endif

#ifdef _DEBUG
const bool ShowDebugOutputDefault = true;
#else
const bool ShowDebugOutputDefault = false;
#endif

UserSettings^ UserSettings::m_current = nullptr;

// NOTE: Not thread-safe
UserSettings^ UserSettings::Current::get()
{
    if (m_current == nullptr)
    {
        m_current = ref new UserSettings();
    }
    return m_current;
}

UserSettings::UserSettings() : m_temperatureUnit(TemperatureUnitDefault), m_showWeatherEffects(ShowWeatherEffectsDefault), m_showDebugOutput(ShowDebugOutputDefault), m_showStarfield(ShowStarfieldDefault)
{
    auto settings = ApplicationData::Current->LocalSettings;

    Object^ key;

    key = settings->Values->Lookup("TemperatureUnit");
    if (key != nullptr)
    {
        String^ value = safe_cast<String^>(key);
        if (value == "Celsius")
        {
            m_temperatureUnit = Weathr::TemperatureUnit::Celsius;
        }
        else
        {
            assert(value == "Fahrenheit");
            m_temperatureUnit = Weathr::TemperatureUnit::Fahrenheit;
        }
    }

    key = settings->Values->Lookup("ShowWeatherEffects");
    if (key != nullptr)
    {
        m_showWeatherEffects = safe_cast<bool>(key);
    }

    key = settings->Values->Lookup("ShowStarfield");
    if (key != nullptr)
    {
        m_showStarfield = safe_cast<bool>(key);
    }

    key = settings->Values->Lookup("ShowDebugOutput");
    if (key != nullptr)
    {
        m_showDebugOutput = safe_cast<bool>(key);
    }
}

// TODO: This and IsFahrenheitSet::set don't feel quite right. 
// Revisit if there's a better way to broadcast the change back to the app's data.
void UserSettings::IsCelsiusSet::set(bool value)
{
    if (!value) return;
    TemperatureUnit = Weathr::TemperatureUnit::Celsius;
    for (auto group : ForecastManager::Current->ForecastGroups)
    {
        for (auto item : group->Items)
        {
            for (const auto& weatherData : item->GetWeatherData())
            {
                weatherData->CurrentDisplayTemperature = weatherData->CurrentTemperatureC;
                weatherData->ExpectedLoDisplayTemperature = weatherData->ExpectedLoC;
                weatherData->ExpectedHiDisplayTemperature = weatherData->ExpectedHiC;
                wchar_t buffer[256];
                swprintf_s(buffer, L"Wind from %s at %d km", weatherData->WindDirection->Data(), weatherData->WindSpeedKm);
                weatherData->DisplayWindSpeed = ref new String(buffer);
            }
        }
    }
}

void UserSettings::IsFahrenheitSet::set(bool value)
{
    if (!value) return;
    TemperatureUnit = Weathr::TemperatureUnit::Fahrenheit;
    for (auto group : ForecastManager::Current->ForecastGroups)
    {
        for (auto item : group->Items)
        {
            for (const auto& weatherData : item->GetWeatherData())
            {
                weatherData->CurrentDisplayTemperature = weatherData->CurrentTemperatureF;
                weatherData->ExpectedLoDisplayTemperature = weatherData->ExpectedLoF;
                weatherData->ExpectedHiDisplayTemperature = weatherData->ExpectedHiF;
                wchar_t buffer[256];
                swprintf_s(buffer, L"Wind from %s at %d mph", weatherData->WindDirection->Data(), weatherData->WindSpeedMph);
                weatherData->DisplayWindSpeed = ref new String(buffer);
            }
        }
    }
}

void UserSettings::SaveProperty(String^ name, Object^ value)
{
    ApplicationData::Current->LocalSettings->Values->Insert(name, value);
}